package ShortestPath_D;

import SeqList.SqList;

import java.util.Scanner;

public class ShortesDmain {
    private static final int M = 10000;

    public static void main(String[] args) throws Exception {
        SqList L = new SqList(10);
        L.insert(0, "城市A");
        L.insert(1, "城市B");
        L.insert(2, "城市C");
        L.insert(3, "城市D");
        L.insert(4, "城市E");
        L.insert(5, "城市F");
        L.insert(6, "城市G");
        L.insert(7, "城市H");
        L.insert(8, "城市I");
        L.insert(9, "城市J");
        int[][] weight1 = {
                {0, M, M, 3, M, M, M, M, M, M},
                {M, 0, 4, M, M, M, M, 5, M, M},
                {M, 4, 0, M, 6, M, M, M, M, M},
                {3, M, M, 0, M, M, 2, M, M, M},
                {M, M, 6, M, 0, 1, M, M, M, M},
                {M, M, M, M, 1, 0, M, M, M, M},
                {M, M, M, 2, M, M, 0, 7, 8, 9},
                {M, 5, M, M, M, M, 7, 0, M, M},
                {M, M, M, M, M, M, 8, M, 0, M},
                {M, M, M, M, M, M, 9, M, M, 0},
        };
        System.out.println("当前所有城市的编号信息如下：");
        System.out.print("    0：城市A");
        System.out.print("    1：城市B");
        System.out.print("    2：城市C");
        System.out.print("    3：城市D");
        System.out.print("    4：城市E");
        System.out.print("    5：城市F");
        System.out.print("    6：城市G");
        System.out.print("    7：城市H");
        System.out.print("    8：城市I");
        System.out.println("    9：城市J");

        //邻接矩阵


        System.out.print("请输入维修队所在城市的代号:");//输入起点代号
        Scanner scan = new Scanner(System.in);
        int start = scan.nextInt();
        System.out.print("请输入需要维修城市的代号:");
        int end   = scan.nextInt();
        int[] shortPath = dijkstra(weight1, start,end);

        for (int i = 0; i < shortPath.length; i++)
            if(i==end)
                System.out.println("维修队从" + start + "号城市出发到" + i + "号城市的维修最短距离为：" + shortPath[i]);
        System.out.println();
    }


    public static int[] dijkstra ( int[][] weight, int start,int end){
        // 接受一个图的权重矩阵，和一个起点编号start（从0编号，顶点存在数组中）
        // 返回一个int[] 数组，表示从start到它的最短路径长度
        int n = weight.length; // 顶点个数
        int[] shortPath = new int[n]; // 存start到其他各点的最短路径
        String[] path = new String[n]; // 存start到其他各点最短路径的字符串表示
        for ( int i = 0; i<n; i++)
            path[i] = new String(start + "-->" + i);
        int[] visited = new int[n]; // 标记当前该顶点的最短路径是否已经求出,1表示已求出

        // 初始化，第一个顶点已经求出
        shortPath[start] = 0;
        visited[start] = 1;

        for (int count = 1; count < n; count++) { // 要加入n-1个顶点
            int k = -1; // 选出一个距离初始顶点start最近的未标记顶点
            int dmin = Integer.MAX_VALUE;
            for (int i = 0; i < n; i++) {
                if (visited[i] == 0 && weight[start][i] < dmin) {
                    dmin = weight[start][i];
                    k = i;
                }
            }

            // 将新选出的顶点标记为已求出最短路径，且到start的最短路径就是dmin
            shortPath[k] = dmin;
            visited[k] = 1;

            // 以k为中间点，修正从start到未访问各点的距离
            for (int i = 0; i < n; i++) {
                //如果 '起始点到当前点距离' + '当前点到某点距离' < '起始点到某点距离', 则更新
                if (visited[i] == 0 && weight[start][k] + weight[k][i] < weight[start][i]) {
                    weight[start][i] = weight[start][k] + weight[k][i];
                    path[i] = path[k] + "-->" + i;
                }
            }
        }
        for (int i = 0; i <n; i++) {
            if(i==end)
                System.out.println("如果维修队在" + start +"号城市，则从"+start+"号城市出发到" + i + "号城市的维修最短路径为：" + path[i]);
        }
        System.out.println("=====================================");
        return shortPath;
    }


}



